package de.gameduell.framework.gui.popup {
	import fl.transitions.TweenEvent;
	
	import de.gameduell.framework.gui.animation.Tweenable;
	import de.gameduell.framework.gui.behavior.DragBehavior;
	import de.gameduell.framework.gui.button.Button;
	import de.gameduell.framework.gui.button.ToggleButton;
	import de.gameduell.framework.gui.util.Blocker;
	import de.gameduell.framework.locale.Locale;
	import de.gameduell.framework.locale.LocalizableSprite;
	import de.gameduell.framework.util.Library;
	
	import flash.display.DisplayObjectContainer;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.utils.Timer;	

	/**
	 * @author cbra
	 */
	public class Popup extends LocalizableSprite {

		public static const HIDE:String = "hide";
		public static const SHOW:String = "show";
		private const ANIMATION:String = "animation";
		
		private const TYPE:String = "popup";
	
		private var popupTimer:Timer;
		protected var library:Library;
		private var popupManager:PopupManager;
		protected var popupPlane:Sprite;
		private var _blocker:Blocker;
		private var _modal:Boolean;
		private var _draggable:Boolean;
		private var _visible:Boolean;		
		private var repeatCount:Number;
		protected var lifeTime:Number;
		private var dragBehavior:DragBehavior;
		private var animation:MovieClip;
		
		protected var locale:Locale;
		protected var _showTween:Tweenable;
		protected var _hideTween:Tweenable;

		public function Popup(libraryID:String,aId:String,aLifeTime:Number,isDraggable:Boolean) {
			super(Library.getInstance().createSprite(libraryID));
			dragBehavior = new DragBehavior();
			id		 	 = aId;
			type		 = TYPE;
			draggable	 = isDraggable;
			library 	 = Library.getInstance();
			repeatCount	 = 1;
			if (aLifeTime!=0){
				addTimer(aLifeTime);
			}else {
				lifeTime = aLifeTime;
			}
			popupManager = PopupManager.getInstance();
			popupPlane	 = popupManager.popupPlane;
			popupManager.register(this);
			_visible 	= false;
			_modal      = false;
			_showTween  = null;
			_hideTween  = null;
			_blocker	= new Blocker(popupPlane,0xFFFFFF,0.25);
			_position.x = popupPlane.stage.stageWidth/2  -_sprite.width/2;
			_position.y = popupPlane.stage.stageHeight/2 -_sprite.height/2;
			if (getChildByName(ANIMATION) != null){
				animation = MovieClip(getChildByName(ANIMATION));
				animation.stop();
			}
			locale = Locale.getInstance();
			locale.localize(this);
		}

		/**
		 * set a tween wich will be used to show the popup
		 * 
		 * @param tween			tween that will be used
		 */
		public function set showTween(tween:Tweenable):void {
			_showTween = tween;
		}

		/**
		 * set a tween wich will be used to hide the popup
		 * 
		 * @param tween			tween that will be used
		 */
		public function set hideTween(tween:Tweenable):void {
			_hideTween = tween;
			_hideTween.addEventListener(TweenEvent.MOTION_FINISH, removePopup);
		}

		public function get timer():Timer{
			return popupTimer;
		}
		
		public function set draggable(isDraggable:Boolean):void{
			_draggable = isDraggable;
			if(isDraggable){
				hitArea = getChildByName("hitter") as Sprite;
				addBehavior(dragBehavior);
			}else{
				removeBehavior(dragBehavior);
			}
		}
		
		public function get draggable():Boolean{
			return _draggable;
		}
		
		public function set modal(isModal:Boolean):void{
			_modal  = isModal;
		}
		
		public function get blocker():Blocker{
			return _blocker;
		}
		
		override public function get visible():Boolean{
			return _visible;
		}

		public function registerButton(buttonId:String, listener:Function = null, offset:int = -1, applyStyle:Boolean = false, customStyleId:String = null):Button{	
			var buttonSprite:Sprite = _sprite.getChildByName(buttonId) as Sprite;
			var localeId:String     = id + Locale.SEPARATOR+buttonSprite.name;
			var button:Button       = new Button(buttonSprite,localeId, true, applyStyle, customStyleId);
			if (offset!= -1){
				button.offset = offset;
			}
			if (listener!=null){
				button.addEventListener(Button.CLICK, listener);
			}
			addLocalizable(button);
			return button;
		}
		
		public function registerToggleButton(buttonId:String, listener:Function = null, offset:int = -1, applyStyle:Boolean = false, customStyleId:String = null):ToggleButton{	
			var buttonSprite:Sprite = _sprite.getChildByName(buttonId) as Sprite;
			var localeId:String     = id + Locale.SEPARATOR+buttonSprite.name;
			var button:ToggleButton = new ToggleButton(buttonSprite, localeId, true, applyStyle, customStyleId);
			if (offset!= -1){
				button.offset = offset;
			}
			if (listener!=null){
				button.addEventListener(Button.CLICK, listener);
				button.addEventListener(ToggleButton.CLICK_TOGGLED, listener);
			}
			addLocalizable(button);
			return button;
		}
		
		private function onTimer(event:TimerEvent):void {
			hide();
		}

		/**
		 * sets a new lifetime and adds a timer
		 */
		public function addTimer(aLifeTime:Number):void {
			lifeTime = aLifeTime;
			popupTimer = new Timer(lifeTime, repeatCount);
			popupTimer.addEventListener(TimerEvent.TIMER, onTimer);
		}
		
		/**
		 * start the timer
		 */
		public function startTimer():void {
			popupTimer.start();
		}

		public function hide(event:Event = null):void {
			if(_visible){
				if (animation!= null){
					animation.stop();
				}
				if (lifeTime!=0){
					popupTimer.stop();
				}
				if(_hideTween != null){
					_hideTween.start();
				}else{
					removePopup();
				}
			}
		}

		public function removePopup(event:Event = null):void {
			_visible = false;
			_blocker.active = false;
				
			if(popupPlane.contains(_sprite)) {
				popupPlane.removeChild(_sprite);
			}
			dragBehavior.stopDrag();
			dispatchEvent(new Event(HIDE));
			
			// this is a bugfix just for firefox flash plugin 10.1:
			// when a popup is over a Sprite and both will be removed in the same frame, 
			// there occurs a strange visual bug, because non-overlapping parts are not cleared
			popupPlane.graphics.clear();
		}

		public function getPopupPlane():Sprite {
			return popupPlane;
		}

		public function show(event:Event = null):void{
			if(!_visible){
				dispatchEvent(new Event(SHOW));
				_visible = true;
				_blocker.active = _modal;
				popupPlane.addChild(_sprite);
				_sprite.x = _position.x;
				_sprite.y = _position.y;
				if(_showTween != null){
					_showTween.start();
				}
				if (lifeTime!=0){
					popupTimer.start();
				}
				if (animation!= null){
					animation.gotoAndPlay(1);
				}
			}
		}
	}
}